package org.xtframe.common.json;

import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

import org.xtframe.common.FileUtil;

public class JSON2Java {

	private static final ScriptEngine jsonParser;

	static {
		try {
//			InputStream is = ClassLoader.getSystemResourceAsStream("org/xtframe/common/json/json2java.js");
//			BufferedReader in = new BufferedReader(new InputStreamReader(is, "utf-8"));
//			StringBuffer buffer = new StringBuffer();
//			String line = in.readLine();	// 读取第一行
//			while (line != null) {          // 如果 line 为空说明读完了
//				buffer.append(line+"\n");   // 将读到的内容添加到 buffer 中
//				line = in.readLine();   // 读取下一行
//			}
//			String init = buffer.toString();
			
			String init = FileUtil.fileReader(Thread.currentThread().getContextClassLoader().getResource("").toURI().getPath()
							+ "org/xtframe/common/json/json2java.js");
			ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
			engine.eval(init);
			jsonParser = engine;
		} catch (Exception e) {
			throw new AssertionError(e);
		}
	}

	@SuppressWarnings("rawtypes")
	public static Object parseJSON(String json) {
		try {
			String eval = "new java.util.concurrent.atomic.AtomicReference(toJava((" + json + ")))";
			AtomicReference ret = (AtomicReference) jsonParser.eval(eval);
			return ret.get();
		} catch (ScriptException e) {
			throw new RuntimeException("Invalid json", e);
		}
	}
	
	public static String optString(Object json) {
		return optString(json, null);
	}
	
	public static String optString(Object json, String def) {
		if(json == null) return def;
		if(json instanceof String) return json.toString();
		return def;
	}
	
	public static Integer optInteger(Object json) {
		return optInteger(json, null);
	}
	
	public static Integer optInteger(Object json, Integer def) {
		if(json == null) return def;
		if(json instanceof Number) return Integer.valueOf(json.toString());
		return def;
	}
	
	public static Boolean optBoolean(Object json) {
		return optBoolean(json, null);
	}
	
	public static Boolean optBoolean(Object json, Boolean def) {
		if(json == null) return def;
		if(json instanceof Boolean) return (Boolean) json;
		return def;
	}
	
	public static Map<String, Object> optMap(Object json) {
		return optMap(json, null);
	}
	
	@SuppressWarnings("unchecked")
	public static Map<String, Object> optMap(Object json, Map<String, Object> def) {
		if(json == null) return def;
		if(json instanceof Map) return (Map<String, Object>) json;
		return def;
	}
	
	public static boolean isArray(Object json) {
		if(json == null 
				|| json instanceof Map 
				|| json instanceof String
				|| json instanceof Number
				|| json instanceof Boolean) return false;
		
		return true;
	}
}
